package com.app.dao;

import java.io.Serializable;

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.springframework.util.Assert;

/**
 * 
 * @author 北京八维博大科技 薛建新
 * @date 2022年2月22日 下午3:07:39
 * @Copyright 北京八维博大科技 参考
 *            https://blog.csdn.net/yuke98727/article/details/52757524<br/>
 *            https://www.cnblogs.com/boywwj/p/8031106.html<br/>
 */
public class ProductInterceptor extends EmptyInterceptor {

	private ThreadLocal<Cached> threadLocal = new ThreadLocal<>();

	@Override
	public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
		threadLocal.set(new Cached(entity.getClass(), id));
		return super.onLoad(entity, id, state, propertyNames, types);
		
	}

	@Override
	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
		threadLocal.set(new Cached(entity.getClass(), id));
		return super.onSave(entity, id, state, propertyNames, types);
	}

	@Override
	public String getEntityName(Object object) {
		return super.getEntityName(object);
	}

	@Override
	public Object getEntity(String entityName, Serializable id) {
		Object o = super.getEntity(entityName, id);
		try {
			threadLocal.set(new Cached(Class.forName(entityName), id));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return o;
	}

	@Override
	public String onPrepareStatement(String sql) {

		Cached cache = threadLocal.get();
		threadLocal.remove();
		if (cache == null) {
			return sql;
		}
		if (cache.clazz == Product.class) {
			ProductKey pk = (ProductKey) cache.getId();
			Assert.notNull(pk.getStoreId(), "product表分区键 StoreId 不能为空");
			sql = sql.replaceAll(Product.TABLE_NAME, "product_" + pk.getStoreId());
		}

		System.out.println(sql);
		return super.onPrepareStatement(sql);
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	static class Cached {
		Class<?> clazz;
		Serializable id;

		Cached(Class<?> clazz, Serializable id) {
			super();
			this.clazz = clazz;
			this.id = id;
		}

		public Class<?> getClazz() {
			return clazz;
		}

		public void setClazz(Class<?> clazz) {
			this.clazz = clazz;
		}

		public Serializable getId() {
			return id;
		}

		public void setId(Serializable id) {
			this.id = id;
		}

	}

}
